package moe.config;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;

public class PropertiesUtil {
	private static final String INIT_CONF = Constants.INIT_CONF_FILE;

	private static Map<String, String> properties = new LinkedHashMap<String, String>();
	private static boolean change = false;

	static {
		loadInitConf();
	}

	public static String getProperty(String name) {
		return properties.get(name);
	}

	public static void setProperty(String name, String value) {
		change = true;
		properties.put(name, value);
	}

	public static String getProperty(String name, String def) {
		if (hasProperty(name)) {
			return properties.get(name);
		}
		return def;
	}

	public static int getInt(String name, int def) {
		if (hasProperty(name)) {
			return Integer.valueOf(properties.get(name));
		}
		return def;
	}

	public static boolean getBoolean(String name, boolean def) {
		if (hasProperty(name)) {
			return properties.get(name).equalsIgnoreCase("true");
		}
		return def;
	}

	public static boolean hasProperty(String name) {
		String value = properties.get(name);
		if (value == null || "".equals(value)) {
			return false;
		}
		return true;
	}

	public static String[] getPropertyKeys() {
		Set<String> set = properties.keySet();
		return set.toArray(new String[set.size()]);
	}

	public static void save() {
		writeInitConf();
	}

	public static Map<String, String> loadPropertiesFile(File file) throws IOException {
		return loadPropertiesFile(new FileInputStream(file));
	}

	public static Map<String, String> loadPropertiesFile(InputStream stream) throws IOException {
		Map<String, String> result = new HashMap<String, String>();
		BufferedReader reader = null;
		try {
			reader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
			String line = null;
			while ((line = reader.readLine()) != null) {
				line = line.trim();
				if ("".equals(line) || line.startsWith("#")) {
					continue;
				} else {
					int index = line.indexOf("=");
					if (index == -1) {
						continue;
					}
					result.put(line.substring(0, index).trim(), line.substring(
							index + 1,
							line.length()).trim());
				}
			}
		} finally {
			if (reader != null) {
				reader.close();
			}
		}
		return result;
	}

	public static void loadInitConf() {
		File file = new File(System.getProperty("user.dir"), INIT_CONF);
		try {
			properties = loadPropertiesFile(file);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	private static void writeInitConf() {
		File file = new File(System.getProperty("user.dir"), INIT_CONF);
		BufferedReader reader = null;
		BufferedWriter writer = null;
		try {
			reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
			String line = null;
			List<String> list = new LinkedList<String>();
			while ((line = reader.readLine()) != null) {
				list.add(line);
			}
			reader.close();
			for (String key : properties.keySet()) {
				ListIterator<String> iterator = list.listIterator();
				boolean find = false;
				while (iterator.hasNext()) {
					if (iterator.next().startsWith(ltrim(key, '#'))) {
						iterator.set(key + "=" + properties.get(key));
						find = true;
						break;
					}
				}
				if (!find) {
					list.add(key + "=" + properties.get(key));
				}
			}
			writer =
					new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));
			for (String l : list) {
				writer.write(l);
				writer.newLine();
			}
			writer.flush();
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			try {
				if (reader != null) {
					reader.close();
				}
				if (writer != null) {
					writer.close();
				}
			} catch (IOException e) {
				//ignore
			}
		}
	}
	
	private static String ltrim(String s, char c) {
		int i = 0;
		while (i < s.length() && s.charAt(i) == c) {
			i += 1;
		}
		return s.substring(i);
	}
}
